feat(ui): add browser Sentry with private source maps - #5709
Conversation
Route errors, unhandled browser exceptions, and failed app-level resource loads in the operator UI were previously invisible outside the Lovable dev sandbox (reportLovableError's window.__lovableEvents bridge is a production no-op). Adds apps/gittensory-ui/src/lib/browser-sentry.ts: a DSN-gated (VITE_SENTRY_DSN) browser Sentry integration. Off by default -- a complete no-op, @sentry/react is never even fetched when unset (a lazy dynamic import, the browser-bundle equivalent of the self-host backend's dynamic @sentry/node import). No Session Replay in this pass -- only init's default error-capture integrations are used. Every event is scrubbed before send: request cookies/headers/body data are stripped outright, secret-shaped keys/values (tokens, bearer headers, JWTs) are redacted recursively, local filesystem paths are replaced, and user is always dropped. Tags stay a small allowlist (route, release, environment, app_surface). Wired into client.ts (init before hydration) and __root.tsx's existing ErrorComponent (captureBrowserError alongside reportLovableError). Source maps are opt-in at the vite.config.ts level (SENTRY_BUILD_SOURCEMAPS=1, "hidden" mode) so the regular Cloudflare Workers Build pipeline -- which is external to this repo's GitHub Actions and already owns apps/gittensory-ui's production deploy -- never produces or serves a .map file. A new, independent ui-sentry-release.yml workflow (behind the same protected `release` environment as the Orb image release) does its own never-deployed build with source maps enabled and uploads them to Sentry as a release artifact whenever apps/gittensory-ui changes on main. Documented in the self-hosting operations docs, including the operator-side wiring needed (VITE_SENTRY_RELEASE must match this workflow's release id in the Cloudflare deploy's own build vars, an external system this repo doesn't control) for source-map symbolication to resolve. Closes #1737
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | fce3815 | Commit Preview URL Branch Preview URL |
Jul 14 2026, 06:27 AM |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5709 +/- ##
=======================================
Coverage 95.05% 95.05%
=======================================
Files 581 581
Lines 46164 46164
Branches 14810 14810
=======================================
Hits 43880 43880
Misses 1523 1523
Partials 761 761
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-14 06:32:12 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 7 non-blocking
Concerns raised — review before merging
📋 Copy for AI agents — paste into your coding agent
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Summary
reportLovableError'swindow.__lovableEventsbridge is a production no-op).apps/gittensory-ui/src/lib/browser-sentry.ts: a DSN-gated (VITE_SENTRY_DSN) browser Sentry integration, off by default — a complete no-op,@sentry/reactis never even fetched when unset (a lazy dynamic import, the browser-bundle equivalent of the self-host backend's dynamic@sentry/nodeimport insrc/selfhost/sentry.ts).init's default error-capture integrations are used;replayIntegration/@sentry/replayare never imported or referenced.useris always dropped — no PII ever leaves the browser. Tags stay a small allowlist:route(pathname only),release,environment,app_surface.client.ts(init before hydration) and__root.tsx's existingErrorComponent(captureBrowserErroralongsidereportLovableError).vite.config.tslevel (SENTRY_BUILD_SOURCEMAPS=1,"hidden"mode) — verified empirically that the regular unflagged build produces zero.mapfiles, and the flagged build produces maps with nosourceMappingURLcomment embedded in the shipped JS. This matters becauseapps/gittensory-ui's production deploy runs through Cloudflare's own Workers Build git integration, not GitHub Actions (confirmed via research — no existing workflow drives it), so the regular build must never produce a servable.mapfile. A new, independentui-sentry-release.ymlworkflow (behind the same protectedreleaseGitHub Environment as the Orb image release) does its own never-deployed build with source maps enabled and uploads them to Sentry as a release artifact wheneverapps/gittensory-uichanges onmain. It fails soft (skips, doesn't error) whenSENTRY_AUTH_TOKENisn't configured, since this is an opt-in operator feature, not a required release artifact.VITE_SENTRY_RELEASEmust match this workflow's release id in Cloudflare's own deploy build vars — an external system this repo doesn't control) for source-map symbolication to actually resolve.Test plan
apps/gittensory-ui/src/lib/browser-sentry.test.ts(new, 18 tests) — no-DSN no-op behavior, scrub coverage (cookies/headers/body/secrets/JWTs/local-paths/recursion-depth-cap/fail-closed), tag application, no-Replay/no-tracing assertion,captureBrowserErrorgatingnpx tsc --noEmitclean acrossapps/gittensory-uieslintclean (0 errors) on all changed files.mapfiles;SENTRY_BUILD_SOURCEMAPS=1build → 116.mapfiles with zerosourceMappingURLcomments embedded in shipped JSnpm run test:ci+npm audit --audit-level=moderate) green: 831 test files passed, 0 failedCloses #1737